/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.cef.designtime.core.utilsgenerator;

import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.io.*;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * Java 类信息
 *
 * @author haoxiaofei
 */
public class JavaClassInfo {
    /**
     * 包名
     */
    private String packageName;
    /**
     * 导入信息
     */
    private ImportInfos importInfos = new ImportInfos();
    /**
     * 文件路径
     */
    private String filePath;

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    private String className;

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    private List<MethodInfo> methods = new ArrayList<>();

    public List<MethodInfo> getMethods() {
        return methods;
    }

    private List<JavaAccessModifier> accessModifiers = new ArrayList<>();

    public List<JavaAccessModifier> getAccessModifiers() {
        return accessModifiers;
    }

    public ImportInfos getImportInfos() {
        return importInfos;
    }

    /**
     * 写入代码
     */
    public void write2File() {
        MetadataProjectService service = SpringBeanUtils.getBean(MetadataProjectService.class);

        String compModulePath = service.getJavaCompProjectPath(filePath);
        String path = Paths.get(compModulePath).resolve(getPackageName().replace(".", "\\")).toString();
        String compositePath = path.replace("\\", File.separator);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("package " + this.packageName + ";\n");
        importInfos.write(stringBuilder);
        stringBuilder.append("\n");
        writeClassHeader(stringBuilder);
        writeMethods(stringBuilder);
        writeClassEnd(stringBuilder);

        File folder = new File(compositePath);
        if (!folder.exists())
            folder.mkdirs();

        String fileName = compositePath + "\\" + className + ".java";
        File f = new File(fileName);

        FileWriter fw;
        try {
            if (!f.exists())
                f.createNewFile();
            OutputStreamWriter out = new OutputStreamWriter(
                new FileOutputStream(f), // true to append
                "UTF-8"
            );

            out.write(stringBuilder.toString());
            out.flush();
            out.close();
        } catch (IOException e) {
            throw new RuntimeException("生成失败", e);
        }
    }

    /**
     * 写入方法
     * @param stringBuilder
     */
    private void writeMethods(StringBuilder stringBuilder) {
        for (MethodInfo methodInfo : getMethods()) {
            stringBuilder.append("\n");
            methodInfo.write(stringBuilder);
        }
        stringBuilder.append("\n");
    }

    private void writeClassEnd(StringBuilder stringBuilder) {
        stringBuilder.append("}");
    }

    private void writeClassHeader(StringBuilder stringBuilder) {
        for (JavaAccessModifier accessModifier : getAccessModifiers())
            stringBuilder.append(accessModifier.toString() + " ");
        stringBuilder.append("class ");
        stringBuilder.append(getClassName()).append("{");
    }

    public void addMethodInfo(MethodInfo methodInfo) {
        getMethods().add(methodInfo);
        getImportInfos().addImportPackage(methodInfo.getReturnType());
        for (ParameterInfo parameterInfo : methodInfo.getParameters())
            getImportInfos().addImportPackage(parameterInfo.getParamType());
    }

    public String getFilePath() {
        return filePath;
    }

    public void setFilePath(String filePath) {
        this.filePath = filePath;
    }
}
